using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Data;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Security.Permissions;
using System.Text;
using System.Xml;
using System.Xml.Schema;
using Oracle.ManagedDataAccess.Client;

namespace OracleInternal.Common
{
	internal class CustomConfigFileReader : ConfigBaseClass
	{
		public const string EdmMappingsElement = "edmMappings";

		public const string DataSource = "dataSource";

		public const string EdmMappingElement = "edmMapping";

		public const string DataType = "dataType";

		public const string Precision = "precision";

		public const string Scale = "scale";

		public const string Add = "add";

		public const string NumberDataType = "number";

		private const string ORA_DEBUG_JDWP = "ORA_DEBUG_JDWP";

		private const string TNS_ADMIN = "TNS_ADMIN";

		private const string LDAP_ADMIN = "LDAP_ADMIN";

		private const string ORACLE_HOME = "ORACLE_HOME";

		private readonly string NETWORK_ADMIN = Path.Combine("network", "admin");

		private readonly string LDAP_ADMIN_DIR = Path.Combine("ldap", "admin");

		private const string LDAPORA = "ldap.ora";

		private const string TNSNAMESORA = "tnsnames.ora";

		private const string SQLNETORA = "sqlnet.ora";

		private Hashtable mapUdtNameToMappingObjConfig = new Hashtable();

		static CustomConfigFileReader()
		{
			AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(LoadODPMDLL);
		}

		public CustomConfigFileReader(bool bIsManaged = false)
		{
			ConfigBaseClass.m_bIsManaged = bIsManaged;
			ConfigBaseClass.m_assemblyVersion = GetExecutingAssemblyVersion();
			GetProcessAndEnvInfo();
			ConfigBaseClass.m_ParseMode = ParseMode.FirstParse;
		}

		[SecurityPermission(SecurityAction.Assert, UnmanagedCode = true)]
		private static void GetProcessAndEnvInfo()
		{
			ConfigBaseClass.CurrentProcess = Process.GetCurrentProcess();
			ConfigBaseClass.m_recoveryServiceHost = Environment.MachineName;
			if (string.Compare(ConfigBaseClass.CurrentProcess.ProcessName, "DOTNET", ignoreCase: true) == 0)
			{
				ConfigBaseClass.ApplicationName = Assembly.GetEntryAssembly()!.GetName().Name;
				ConfigBaseClass.CoreRunTimeExt = "dll";
			}
			else
			{
				ConfigBaseClass.ApplicationName = ConfigBaseClass.CurrentProcess.ProcessName;
				ConfigBaseClass.CoreRunTimeExt = "exe";
			}
		}

		internal static Version GetExecutingAssemblyVersion()
		{
			return Assembly.GetExecutingAssembly().GetName().Version;
		}

		private static Assembly LoadODPMDLL(object sender, ResolveEventArgs args)
		{
			string name = new AssemblyName(args.Name).Name;
			switch (name)
			{
			case "Oracle.ManagedDataAccess":
			{
				Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
				foreach (Assembly assembly2 in assemblies)
				{
					if (assembly2.FullName!.Equals(args.Name))
					{
						return assembly2;
					}
				}
				break;
			}
			case "Oracle.ManagedDataAccessDTC":
			case "Oracle.ManagedDataAccessIOP":
			{
				Assembly assembly = null;
				string text = null;
				string text2 = name;
				text = ((IntPtr.Size != 8) ? "x86" : "x64");
				try
				{
					text2 = new Uri(Path.Combine(Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().CodeBase), text), name + ".dll")).LocalPath;
					assembly = Assembly.LoadFrom(text2);
				}
				catch (Exception ex)
				{
					if (ProviderConfig.m_bTraceLevelPublic)
					{
						Trace.Write(OracleTraceLevel.Public, OracleTraceTag.Entry, OracleTraceClassName.CustomConfigFileReader, OracleTraceFuncName.LoadODPMDLL, "AssemblyResolve(" + text2 + ") failed with [" + ex.ToString() + "]");
					}
				}
				if (assembly != null)
				{
					return assembly;
				}
				break;
			}
			}
			return null;
		}

		internal string[] GetName(StreamReader strmRdr, out string leftover)
		{
			string[] result = null;
			int num = -1;
			leftover = "";
			while (num == -1 && !strmRdr.EndOfStream)
			{
				string text = strmRdr.ReadLine()!.Trim();
				if (text.Length > 0 && text[0] == '#')
				{
					continue;
				}
				num = text.IndexOf('=');
				if (num != -1)
				{
					result = (from s in text.Substring(0, num).Split(',')
						select s.Trim() into s
						where s != string.Empty
						select s).ToArray();
					leftover = text.Substring(num + 1);
				}
			}
			return result;
		}

		internal string GetValue(StreamReader strmRdr, string leftover)
		{
			bool flag = false;
			string text = "";
			string text2 = "";
			int num = 0;
			int num2 = -1;
			try
			{
				text2 = leftover.Trim();
				while ((text2.Length == 0 || text2[0] == '#') && !strmRdr.EndOfStream)
				{
					text2 = strmRdr.ReadLine()!.Trim();
				}
				if (text2.Contains('#'))
				{
					num2 = text2.IndexOf('#');
					if (num2 != -1)
					{
						text2 = text2.Substring(0, num2);
						text2.Trim();
					}
				}
				if (text2.Length <= 0 || text2[0] != '(')
				{
					return text2.Trim();
				}
				while (true)
				{
					if (text2.Length > 0 && text2[0] != '#')
					{
						flag = false;
						int i;
						for (i = 0; i < text2.Length; i++)
						{
							if (flag)
							{
								flag = false;
								continue;
							}
							switch (text2[i])
							{
							case '(':
								num++;
								break;
							case ')':
								num--;
								break;
							case '#':
								text2 = text2.Remove(i--);
								break;
							case '\\':
								if (i + 1 == text2.Length)
								{
									text2 = text2.Remove(i--, 1);
									flag = true;
								}
								else if (ConfigBaseClass.m_parens.Contains(text2[i + 1]))
								{
									text2 = text2.Remove(i--, 1);
								}
								else
								{
									flag = true;
								}
								break;
							}
							if (num == 0 && i + 1 != text2.Length)
							{
								string text3 = text2.Substring(i + 1, text2.Length - (i + 1)).Trim();
								if (!string.IsNullOrEmpty(text3) && text3[0] != '#' && text3[0] != ')')
								{
									return null;
								}
								text2 = text2.Remove(i + 1);
							}
						}
						text += text2.Substring(0, i);
					}
					if (num != 0)
					{
						int num3;
						if ((num3 = strmRdr.Peek()) != -1)
						{
							if (ConfigBaseClass.m_allowedCont.Contains((char)num3) || ((ushort)num3 == 41 && num == 1) || flag)
							{
								if (!strmRdr.EndOfStream)
								{
									if ((text2 = strmRdr.ReadLine()!.Trim()).Length < 0)
									{
										return text;
									}
									continue;
								}
								return text;
							}
							return text;
						}
						return text;
					}
					break;
				}
				return text;
			}
			catch (Exception)
			{
				return text;
			}
		}

		internal override void ParseConfigFile()
		{
			ParseAndCacheConfigParams();
			FieldInfo[] fields = typeof(ConfigBaseClass).GetFields(BindingFlags.Static | BindingFlags.NonPublic);
			foreach (FieldInfo fieldInfo in fields)
			{
				ConfigurationAttribute configurationAttribute = Attribute.GetCustomAttribute(fieldInfo, typeof(ConfigurationAttribute)) as ConfigurationAttribute;
				if (configurationAttribute == null)
				{
					continue;
				}
				string text = (string)ConfigBaseClass.m_configParameters[configurationAttribute.ConfigEntry];
				if (text == null || text.Length == 0)
				{
					continue;
				}
				if (fieldInfo.FieldType == typeof(ushort))
				{
					fieldInfo.SetValue(null, ushort.Parse(text));
				}
				else if (fieldInfo.FieldType == typeof(int))
				{
					fieldInfo.SetValue(null, int.Parse(text));
				}
				else if (fieldInfo.FieldType == typeof(uint))
				{
					fieldInfo.SetValue(null, uint.Parse(text));
				}
				else if (fieldInfo.FieldType == typeof(long))
				{
					fieldInfo.SetValue(null, long.Parse(text));
				}
				else
				{
					if (fieldInfo.FieldType == typeof(string))
					{
						fieldInfo.SetValue(null, text);
						if (!(fieldInfo.Name == "m_serviceRelocationTimeout"))
						{
							continue;
						}
						try
						{
							string[] array = ConfigBaseClass.m_serviceRelocationTimeout.Split('+');
							if (array.Length == 1)
							{
								array[0] = array[0].Trim();
								try
								{
									if (string.Equals(array[0], "drain_timeout", StringComparison.InvariantCultureIgnoreCase))
									{
										ConfigBaseClass.s_bDrainTimeoutInSRCT = true;
									}
									else
									{
										ConfigBaseClass.srctOffset = Convert.ToInt32(array[0]);
									}
									ConfigBaseClass.s_bFromConfigSRCT = true;
								}
								catch
								{
									throw;
								}
								continue;
							}
							if (array.Length == 2)
							{
								array[0] = array[0].Trim();
								array[1] = array[1].Trim();
								if (string.Equals(array[0], "drain_timeout", StringComparison.InvariantCultureIgnoreCase))
								{
									ConfigBaseClass.s_bDrainTimeoutInSRCT = true;
									ConfigBaseClass.s_bFromConfigSRCT = true;
									ConfigBaseClass.srctOffset = Convert.ToInt32(array[1]);
									continue;
								}
								if (string.Equals(array[1], "drain_timeout", StringComparison.InvariantCultureIgnoreCase))
								{
									ConfigBaseClass.s_bDrainTimeoutInSRCT = true;
									ConfigBaseClass.s_bFromConfigSRCT = true;
									ConfigBaseClass.srctOffset = Convert.ToInt32(array[0]);
									continue;
								}
								throw new Exception();
							}
							throw new Exception();
						}
						catch (Exception)
						{
							throw new OracleException(ResourceStringConstants.CON_STR_INVALID_VALUE, string.Empty, string.Empty, OracleStringResourceManager.GetErrorMesg(ResourceStringConstants.CON_STR_INVALID_VALUE, configurationAttribute.ConfigEntry, text));
						}
					}
					if (fieldInfo.FieldType == typeof(bool))
					{
						try
						{
							fieldInfo.SetValue(null, ParseBooleanConfigValue(text));
						}
						catch (Exception)
						{
							throw new OracleException(ResourceStringConstants.CON_STR_INVALID_VALUE, string.Empty, string.Empty, OracleStringResourceManager.GetErrorMesg(ResourceStringConstants.CON_STR_INVALID_VALUE, configurationAttribute.ConfigEntry, text));
						}
					}
					else if (fieldInfo.FieldType == typeof(PromotableTransaction))
					{
						if (string.Equals(text, "local", StringComparison.OrdinalIgnoreCase))
						{
							fieldInfo.SetValue(null, PromotableTransaction.Local);
						}
						else if (string.Equals(text, "promotable", StringComparison.OrdinalIgnoreCase))
						{
							fieldInfo.SetValue(null, PromotableTransaction.Promotable);
						}
					}
					else
					{
						if (!(fieldInfo.FieldType == typeof(TimeSpan)))
						{
							throw new OracleException(ResourceStringConstants.CON_STR_INVALID_VALUE, string.Empty, string.Empty, OracleStringResourceManager.GetErrorMesg(ResourceStringConstants.CON_STR_INVALID_VALUE, configurationAttribute.ConfigEntry, text));
						}
						fieldInfo.SetValue(null, TimeSpan.FromSeconds(double.Parse(text)));
					}
				}
			}
			if (ConfigBaseClass.m_TraceFileMaxSize <= 0)
			{
				ConfigBaseClass.m_TraceFileMaxSize = 104857600L;
			}
			else
			{
				ConfigBaseClass.m_TraceFileMaxSize = ConfigBaseClass.m_TraceFileMaxSize * 1024 * 1024;
			}
			if (ConfigBaseClass.m_TraceLevel < 0)
			{
				ConfigBaseClass.m_TraceLevel = 0;
			}
			if (ConfigBaseClass.m_TraceOption < 0)
			{
				ConfigBaseClass.m_TraceOption = 0;
			}
			ConfigBaseClass.m_configParametersClone = (Hashtable)ConfigBaseClass.m_configParameters.Clone();
			ConfigBaseClass.m_sqlnetOraLoc = ProviderConfig.NewOraFileLoc(OraFiles.SqlNet);
			ProviderConfig.NewOraFileParams(OraFiles.SqlNet, ConfigBaseClass.m_sqlnetOraLoc, ConfigBaseClass.m_configParameters);
			try
			{
				if (!string.IsNullOrEmpty((string)ConfigBaseClass.m_configParameters["sqlnet.kerberos5_conf"]))
				{
					Environment.SetEnvironmentVariable("KRB5_CONFIG", (string)ConfigBaseClass.m_configParameters["sqlnet.kerberos5_conf"]);
				}
			}
			catch
			{
				if (ProviderConfig.m_bTraceLevelPublic)
				{
					Trace.Write(OracleTraceLevel.Config, OracleTraceTag.Environment, OracleTraceClassName.CustomConfigFileReader, OracleTraceFuncName.ParseConfigFile, "KRB5_CONFIG : Unable to set environment variable.");
				}
			}
			if (ConfigBaseClass.s_bLegacyEdmMappingPresent)
			{
				ValidateEdmMapping();
			}
			if (ConfigBaseClass.m_TraceLevel > 0)
			{
				ProviderConfig.TraceConfigAndEnvParams();
			}
		}

		private void ParseAndCacheConfigParams()
		{
		}

		internal void ParseSubSection(XmlNode subSectionNode, ref Hashtable schemaTable, ArrayList filterNodes = null)
		{
			if (subSectionNode == null)
			{
				return;
			}
			bool flag = filterNodes != null && filterNodes.Count > 0;
			foreach (XmlNode childNode in subSectionNode.ChildNodes)
			{
				string name = childNode.Name;
				if (!flag || filterNodes.Contains(name))
				{
					switch (name)
					{
					case "dataSources":
						ParseDataSourcesElement(childNode);
						break;
					case "onsConfig":
						ParseONSConfigElement(childNode);
						break;
					case "LDAPsettings":
						ParseLDAPsettingsElement(childNode);
						break;
					case "settings":
						ParseSettingsElement(childNode);
						break;
					case "edmMappings":
						ParseEdmMappingsElement(childNode);
						break;
					case "implicitRefCursor":
						ParseImpRefCursorElement(childNode, ref schemaTable);
						break;
					case "distributedTransaction":
						ParseDistTxnElement(childNode);
						break;
					case "connectionPools":
						ParseConnectionPoolsElement(childNode);
						break;
					}
				}
			}
		}

		private void ParseConnectionPoolsElement(XmlNode connectionPoolsNode)
		{
			if (connectionPoolsNode == null)
			{
				return;
			}
			foreach (XmlNode childNode in connectionPoolsNode.ChildNodes)
			{
				if (childNode.Attributes != null)
				{
					string key = childNode.Attributes["connectionString"].Value.Trim();
					ConfigBaseClass.m_connectionPoolNameMapping[key] = childNode.Attributes["poolName"].Value.Trim();
				}
			}
		}

		private bool ParseBooleanConfigValue(string configValue)
		{
			if (int.TryParse(configValue, out var result))
			{
				if (result == 0)
				{
					return false;
				}
				return true;
			}
			return bool.Parse(configValue);
		}

		private void ParseDataSourcesElement(XmlNode dataSourceNode)
		{
			if (dataSourceNode == null)
			{
				return;
			}
			foreach (XmlNode childNode in dataSourceNode.ChildNodes)
			{
				if (childNode.Attributes == null)
				{
					continue;
				}
				string[] array = (from s in childNode.Attributes["alias"].Value.Trim().Split(',')
					select s.Trim() into s
					where s != string.Empty
					select s).ToArray();
				foreach (string key in array)
				{
					if (ConfigBaseClass.m_ParseMode == ParseMode.ReParseTnsNames)
					{
						if (!ConfigBaseClass.m_configDataSourcesMap.Contains(key))
						{
							ConfigBaseClass.m_configDataSourcesMap[key] = childNode.Attributes["descriptor"].Value.Trim();
						}
					}
					else
					{
						ConfigBaseClass.m_configDataSourcesMap[key] = childNode.Attributes["descriptor"].Value.Trim();
					}
				}
			}
		}

		private void ParseDistTxnElement(XmlNode distTxnNode)
		{
			if (distTxnNode == null)
			{
				return;
			}
			foreach (XmlNode childNode in distTxnNode.ChildNodes)
			{
				if (childNode.Attributes == null)
				{
					continue;
				}
				string a = childNode.Attributes["name"].Value.Trim();
				string text = childNode.Attributes["value"].Value.Trim();
				if (string.Equals(a, "omtsreco_ip_address", StringComparison.InvariantCultureIgnoreCase))
				{
					if (!string.IsNullOrEmpty(text))
					{
						ConfigBaseClass.m_recoveryServiceHost = text;
					}
				}
				else if (string.Equals(a, "omtsreco_port", StringComparison.InvariantCultureIgnoreCase))
				{
					try
					{
						ConfigBaseClass.m_recoveryServicePort = ushort.Parse(text);
					}
					catch
					{
					}
				}
				else if (string.Equals(a, "oramts_sess_txntimetolive", StringComparison.InvariantCultureIgnoreCase))
				{
					try
					{
						ConfigBaseClass.m_dtcTxnTimeout = uint.Parse(text);
					}
					catch
					{
					}
				}
				else if (string.Equals(a, "UseManagedDTC", StringComparison.InvariantCultureIgnoreCase))
				{
					try
					{
						ConfigBaseClass.m_dtcUseDTCDLL = ParseBooleanConfigValue(text);
					}
					catch
					{
					}
				}
			}
		}

		private void ParseUdtMappingsElement(XmlNode udtMappingsNode)
		{
			string text = "";
			string text2 = "";
			foreach (XmlNode childNode in udtMappingsNode.ChildNodes)
			{
				if (childNode.Attributes == null)
				{
					continue;
				}
				string text3 = childNode.Attributes["typeName"].Value.Trim();
				if (text3 != null && text3.Length > 0)
				{
					NameValueCollection nameValueCollection = new NameValueCollection();
					string text4 = "typeName='" + text3 + "'";
					nameValueCollection["typeName"] = text3;
					nameValueCollection["factoryName"] = childNode.Attributes["factoryName"].Value.Trim();
					if (childNode.Attributes["schemaName"] != null && childNode.Attributes["schemaName"].Value.Length > 0)
					{
						text2 = (nameValueCollection["schemaName"] = childNode.Attributes["schemaName"].Value.Trim());
						text4 = "schemaName='" + text2 + "' " + text4;
					}
					if (childNode.Attributes["dataSource"] != null && childNode.Attributes["dataSource"].Value.Length > 0)
					{
						text = (nameValueCollection["dataSource"] = childNode.Attributes["dataSource"].Value.Trim().ToUpper());
						text4 = "dataSource='" + text + "' " + text4;
					}
					mapUdtNameToMappingObjConfig[text4] = nameValueCollection;
				}
			}
		}

		private void ParseImpRefCursorElement(XmlNode node, ref Hashtable schemaTable)
		{
			foreach (XmlNode childNode in node.ChildNodes)
			{
				if (!(childNode.Name == "storedProcedure"))
				{
					continue;
				}
				string value = childNode.Attributes["name"].Value.Trim();
				string text = null;
				if (childNode.Attributes["schema"] != null)
				{
					text = childNode.Attributes["schema"].Value.Trim();
				}
				string storedProcKey = new StringBuilder().Append(string.IsNullOrEmpty(text) ? "" : text).Append(string.IsNullOrEmpty(text) ? "" : ".").Append(value)
					.ToString();
				GetKeyInProperCase(ref storedProcKey);
				if (!schemaTable.Contains(storedProcKey))
				{
					StoredProcedureInfo value2 = new StoredProcedureInfo();
					schemaTable.Add(storedProcKey, value2);
				}
				foreach (XmlNode childNode2 in childNode.ChildNodes)
				{
					if (childNode2.Name == "refCursor")
					{
						AddInfoForRefCursor(storedProcKey, childNode2, ref schemaTable);
					}
				}
			}
		}

		private void ParseLDAPsettingsElement(XmlNode settingsNode)
		{
			foreach (XmlNode childNode in settingsNode.ChildNodes)
			{
				if (childNode.Attributes != null)
				{
					string key = childNode.Attributes["name"].Value.Trim();
					ConfigBaseClass.m_LDAPconfigParameters[key] = childNode.Attributes["value"].Value.Trim();
					ConfigBaseClass.m_LDAPCfParamFrAppConfig[key] = true;
				}
			}
		}

		private void ParseONSConfigElement(XmlNode ONSConfigNode)
		{
			if (ONSConfigNode == null)
			{
				return;
			}
			ConfigBaseClass.m_ONSMode = (OnsConfigMode)Enum.Parse(typeof(OnsConfigMode), ONSConfigNode.Attributes[ConfigInfo.ONSMode].Value.Trim());
			if (ONSConfigNode.Attributes[ConfigInfo.ONSConfigFile] != null)
			{
				ConfigBaseClass.m_ONSConfigFile = ONSConfigNode.Attributes[ConfigInfo.ONSConfigFile].Value.Trim();
			}
			else if (ConfigBaseClass.m_ONSMode == OnsConfigMode.local)
			{
				throw new ArgumentNullException("onsConfig." + ConfigInfo.ONSConfigFile);
			}
			if (ConfigBaseClass.m_ONSMode != OnsConfigMode.remote)
			{
				return;
			}
			if (!string.IsNullOrWhiteSpace(ConfigBaseClass.m_ONSConfigFile))
			{
				ConfigBaseClass.m_nodeListFromConfFile = GetPropertyFromONSConfig(ConfigBaseClass.m_ONSConfigFile, ConfigInfo.ONSNodes);
			}
			foreach (XmlNode childNode in ONSConfigNode.ChildNodes)
			{
				if (!childNode.HasChildNodes)
				{
					continue;
				}
				if (childNode.Name == "settings")
				{
					foreach (XmlNode childNode2 in childNode.ChildNodes)
					{
						if (childNode2.Attributes != null)
						{
							string strA = childNode2.Attributes["name"].Value.Trim();
							if (string.Compare(strA, ConfigInfo.ONSWalletLocation, StringComparison.CurrentCultureIgnoreCase) == 0)
							{
								ConfigBaseClass.m_ONSWalletLocation = childNode2.Attributes["value"].Value.Trim();
							}
							else if (string.Compare(strA, ConfigInfo.ONSProtocol, StringComparison.CurrentCultureIgnoreCase) == 0)
							{
								ConfigBaseClass.m_ONSProtocol = childNode2.Attributes["value"].Value.Trim();
							}
						}
					}
				}
				else if (childNode.Name == "ons")
				{
					ParseONSElement(childNode);
				}
			}
		}

		private void ParseONSElement(XmlNode ONSNode)
		{
			string text = null;
			string value = null;
			if (ONSNode.Attributes != null)
			{
				text = ONSNode.Attributes[ConfigInfo.ONSDatabase].Value.Trim();
			}
			foreach (XmlNode childNode in ONSNode.ChildNodes)
			{
				if (childNode.Attributes != null)
				{
					string text2 = childNode.Attributes["name"].Value.Trim();
					string text3 = childNode.Attributes["value"].Value.Trim();
					if (text2.Equals("nodeList"))
					{
						value = text3;
					}
				}
			}
			if (string.IsNullOrWhiteSpace(value))
			{
				throw new ArgumentNullException("onsConfig.nodeList");
			}
			Dictionary<string, string> dictionary = new Dictionary<string, string>();
			dictionary.Add("nodeList", value);
			ConfigBaseClass.m_ONSMapping.Add(text.ToLowerInvariant(), dictionary);
		}

		internal string GetPropertyFromONSConfig(string ONSConfigFile, string onsConfigProperty)
		{
			string result = null;
			if (File.Exists(ONSConfigFile))
			{
				using (StreamReader strmRdr = new StreamReader(ONSConfigFile))
				{
					string leftover;
					string[] name = GetName(strmRdr, out leftover);
					while (name != null && name.Length != 0)
					{
						string value = GetValue(strmRdr, leftover);
						string[] array = name;
						for (int i = 0; i < array.Length; i++)
						{
							if (array[i].ToLowerInvariant() == onsConfigProperty)
							{
								result = value;
							}
							name = GetName(strmRdr, out leftover);
						}
					}
					return result;
				}
			}
			throw new FileNotFoundException(OracleStringResourceManager.GetErrorMesg(ResourceStringConstants.ONS_FILE_NOT_EXIST, "Config File", ONSConfigFile));
		}

		private void AddInfoForRefCursor(string storedProcKey, XmlNode refCursorNode, ref Hashtable schemaTable)
		{
			if (refCursorNode.Attributes != null)
			{
				bool isInfoBasedOnName = false;
				RefCursorInfo refCursorInfo = new RefCursorInfo();
				XmlAttribute xmlAttribute = refCursorNode.Attributes["name"];
				XmlAttribute xmlAttribute2 = refCursorNode.Attributes["position"];
				string s;
				string name;
				if (xmlAttribute2 != null && !string.IsNullOrEmpty(s = xmlAttribute2.Value.Trim()))
				{
					refCursorInfo.position = int.Parse(s);
					isInfoBasedOnName = false;
				}
				else if (xmlAttribute != null && !string.IsNullOrEmpty(name = xmlAttribute.Value.Trim()))
				{
					refCursorInfo.name = name;
					isInfoBasedOnName = true;
					refCursorInfo.position = -1;
				}
				else
				{
					string messageForTrace = "Neither RefCursor name nor position is present in " + storedProcKey;
					string messageForException = storedProcKey + "  refCursor";
					ThrowExceptionForRefCursor(messageForTrace, messageForException);
				}
				foreach (XmlNode childNode in refCursorNode.ChildNodes)
				{
					string name2 = childNode.Name;
					if (!(name2 == "bindInfo"))
					{
						if (name2 == "metadata")
						{
							AddMetadataForRefCursor(storedProcKey, childNode, ref refCursorInfo, isInfoBasedOnName, ref schemaTable);
						}
					}
					else
					{
						AddBindInfoForRefCursor(storedProcKey, childNode, ref refCursorInfo, isInfoBasedOnName, ref schemaTable);
					}
				}
			}
			else
			{
				string messageForTrace2 = "Neither RefCursor name nor position is present in stored procedure " + storedProcKey;
				string messageForException2 = storedProcKey + "  refCursor";
				ThrowExceptionForRefCursor(messageForTrace2, messageForException2);
			}
		}

		private void AddBindInfoForRefCursor(string storedProcKey, XmlNode bindInfoNode, ref RefCursorInfo refCursorInfo, bool isInfoBasedOnName, ref Hashtable schemaTable)
		{
			string value = bindInfoNode.Attributes["mode"].Value;
			StoredProcedureInfo storedProcedureInfo = (StoredProcedureInfo)schemaTable[storedProcKey];
			int num = 0;
			if (value != "Implicit")
			{
				refCursorInfo.mode = (ParameterDirection)Enum.Parse(typeof(ParameterDirection), value, ignoreCase: true);
				foreach (RefCursorInfo refCursor in storedProcedureInfo.m_refCursors)
				{
					if (isInfoBasedOnName)
					{
						if (refCursor.name.Length > 0 && refCursor.name.Equals(refCursorInfo.name))
						{
							storedProcedureInfo.m_refCursors.RemoveAt(num);
							break;
						}
					}
					else if (refCursor.position >= refCursorInfo.position)
					{
						if (refCursor.position == refCursorInfo.position)
						{
							storedProcedureInfo.m_refCursors.RemoveAt(num);
						}
						storedProcedureInfo.m_refCursors.Insert(num, refCursorInfo);
						return;
					}
					num++;
				}
				storedProcedureInfo.m_refCursors.Add(refCursorInfo);
				return;
			}
			foreach (RefCursorInfo implicitlyRetRefCursor in storedProcedureInfo.m_implicitlyRetRefCursors)
			{
				if (isInfoBasedOnName)
				{
					if (implicitlyRetRefCursor.name.Length > 0 && implicitlyRetRefCursor.name.Equals(refCursorInfo.name))
					{
						storedProcedureInfo.m_implicitlyRetRefCursors.RemoveAt(num);
						break;
					}
				}
				else if (implicitlyRetRefCursor.position >= refCursorInfo.position)
				{
					if (implicitlyRetRefCursor.position == refCursorInfo.position)
					{
						storedProcedureInfo.m_implicitlyRetRefCursors.RemoveAt(num);
					}
					storedProcedureInfo.m_implicitlyRetRefCursors.Insert(num, refCursorInfo);
					return;
				}
				num++;
			}
			storedProcedureInfo.m_implicitlyRetRefCursors.Add(refCursorInfo);
		}

		private void AddMetadataForRefCursor(string storedProcKey, XmlNode metadataNode, ref RefCursorInfo refCursorInfo, bool isInfoBasedOnName, ref Hashtable schemaTable)
		{
			int num = int.Parse(metadataNode.Attributes["columnOrdinal"].Value.Trim());
			DataRow dataRow = refCursorInfo.columnInfo.NewRow();
			foreach (XmlAttribute attribute in metadataNode.Attributes)
			{
				string text = attribute.Value.Trim();
				switch (attribute.Name.ToUpperInvariant())
				{
				case "COLUMNORDINAL":
					dataRow["ColumnOrdinal"] = num;
					break;
				case "COLUMNNAME":
					dataRow["ColumnName"] = GetAttrValueInProperCase(text);
					break;
				case "COLUMNSIZE":
					dataRow["ColumnSize"] = int.Parse(text);
					break;
				case "NUMERICPRECISION":
					dataRow["NumericPrecision"] = int.Parse(text);
					break;
				case "NUMERICSCALE":
					dataRow["NumericScale"] = int.Parse(text);
					break;
				case "ISUNIQUE":
					dataRow["IsUnique"] = bool.Parse(text);
					break;
				case "ISKEY":
					dataRow["IsKey"] = bool.Parse(text);
					if ((bool)dataRow["IsKey"])
					{
						refCursorInfo.isPrimaryKeyPresent = true;
					}
					break;
				case "ISROWID":
					dataRow["IsRowID"] = bool.Parse(text);
					break;
				case "BASECOLUMNNAME":
					dataRow["BaseColumnName"] = GetAttrValueInProperCase(text);
					break;
				case "BASESCHEMANAME":
					dataRow["BaseSchemaName"] = GetAttrValueInProperCase(text);
					break;
				case "BASETABLENAME":
					dataRow["BaseTableName"] = GetAttrValueInProperCase(text);
					break;
				case "DATATYPE":
					dataRow["DataType"] = Type.GetType(text);
					break;
				case "PROVIDERTYPE":
					dataRow["ProviderType"] = (OracleDbType)Enum.Parse(typeof(OracleDbType), text.Split('.')[text.Split('.').Length - 1], ignoreCase: true);
					break;
				case "ALLOWDBNULL":
					dataRow["AllowDBNull"] = bool.Parse(text);
					break;
				case "ISALIASED":
					dataRow["IsAliased"] = bool.Parse(text);
					break;
				case "ISBYTESEMANTIC":
					dataRow["IsByteSemantic"] = bool.Parse(text);
					break;
				case "ISEXPRESSION":
					dataRow["IsExpression"] = bool.Parse(text);
					break;
				case "ISHIDDEN":
					dataRow["IsHidden"] = bool.Parse(text);
					break;
				case "ISREADONLY":
					dataRow["IsReadOnly"] = bool.Parse(text);
					break;
				case "ISLONG":
					dataRow["IsLong"] = bool.Parse(text);
					break;
				case "UDTTYPENAME":
					dataRow["UdtTypeName"] = GetAttrValueInProperCase(text);
					break;
				case "NATIVEDATATYPE":
					dataRow["NativeDataType"] = GetAttrValueInProperCase(text);
					break;
				case "PROVIDERDBTYPE":
					dataRow["ProviderDBType"] = (DbType)Enum.Parse(typeof(DbType), text.Split('.')[text.Split('.').Length - 1], ignoreCase: true);
					break;
				case "OBJECTNAME":
					dataRow["ObjectName"] = GetAttrValueInProperCase(text);
					break;
				}
			}
			if (refCursorInfo.columnInfo.Rows.Count > num)
			{
				refCursorInfo.columnInfo.Rows.InsertAt(dataRow, num);
			}
			else
			{
				refCursorInfo.columnInfo.Rows.Add(dataRow);
			}
			refCursorInfo.columnInfo.AcceptChanges();
		}

		private void ThrowExceptionForRefCursor(string messageForTrace, string messageForException)
		{
		}

		private void ParseSettingsElement(XmlNode settingsNode)
		{
			foreach (XmlNode childNode in settingsNode.ChildNodes)
			{
				if (childNode.Attributes != null)
				{
					string key = childNode.Attributes["name"].Value.Trim();
					ConfigBaseClass.m_configParameters[key] = childNode.Attributes["value"].Value.Trim();
					ConfigBaseClass.m_configParameters_nonsqlnet[key] = ConfigBaseClass.m_configParameters[key];
					ConfigBaseClass.m_configParamFrAppConfig[key] = true;
				}
			}
		}

		private void ParseEdmMappingsElement(XmlNode edmMappingsNode)
		{
			InitEdmMapping();
			if (edmMappingsNode == null)
			{
				return;
			}
			foreach (XmlNode childNode in edmMappingsNode.ChildNodes)
			{
				if (childNode.Attributes == null || !childNode.HasChildNodes)
				{
					continue;
				}
				if (childNode.Name == "edmMapping")
				{
					ConfigBaseClass.s_bLegacyEdmMappingPresent = true;
					string text = childNode.Attributes["dataType"].Value.Trim();
					if (!(text.ToLowerInvariant() == "number"))
					{
						if (ProviderConfig.m_bTraceLevelPublic)
						{
							Trace.Write(OracleTraceLevel.Public, OracleTraceTag.Error, OracleTraceClassName.RegistryUtility, OracleTraceFuncName.ParseEdmMappingsElement, "(EDMMAPPING) DataType '" + text + "' is invalid");
						}
						throw new ConfigurationErrorsException(OracleStringResourceManager.GetErrorMesg(ResourceStringConstants.ODP_INVALID_VALUE, "DataType '" + text + "'"));
					}
					foreach (XmlNode childNode2 in childNode.ChildNodes)
					{
						if (childNode2.Name == "add")
						{
							string key = childNode2.Attributes["name"].Value.Trim().ToUpperInvariant();
							if (ConfigBaseClass.s_edmMapping.ContainsKey(key))
							{
								ConfigBaseClass.s_edmMapping[key] = int.Parse(childNode2.Attributes["precision"].Value.Trim());
							}
						}
					}
				}
				else
				{
					if (!(childNode.Name == "edmNumberMapping"))
					{
						continue;
					}
					ConfigBaseClass.s_bEdmNumberMappingPresent = true;
					foreach (XmlNode childNode3 in childNode.ChildNodes)
					{
						if (!(childNode3.Name == "add") || !(childNode3.Attributes["DBType"].Value.Trim().ToLowerInvariant() == "number"))
						{
							continue;
						}
						string key2 = childNode3.Attributes["NETType"].Value.Trim().ToUpperInvariant();
						int num = int.Parse(childNode3.Attributes["MinPrecision"].Value.Trim());
						int num2 = int.Parse(childNode3.Attributes["MaxPrecision"].Value.Trim());
						if (ConfigBaseClass.s_EdmMappingToDbType.ContainsKey(key2) && ConfigBaseClass.s_EdmMappingToDbType.TryGetValue(key2, out var value))
						{
							for (int i = num; i <= num2; i++)
							{
								ConfigBaseClass.s_edmPrecisonMapping[i] = value;
							}
						}
					}
				}
			}
		}

		internal void InitEdmMapping()
		{
			ConfigBaseClass.s_edmMapping["BOOL"] = -2;
			ConfigBaseClass.s_edmMapping["BYTE"] = -1;
			ConfigBaseClass.s_edmMapping["INT16"] = 5;
			ConfigBaseClass.s_edmMapping["INT32"] = 10;
			ConfigBaseClass.s_edmMapping["INT64"] = 19;
		}

		internal void ValidateBaseDocument(XmlDocument doc)
		{
			CustomConfigFileReader @object = new CustomConfigFileReader(ConfigBaseClass.m_bIsManaged);
			doc.Schemas.Add(null, new XmlTextReader(Assembly.GetExecutingAssembly().GetManifestResourceStream("Oracle.ManagedDataAccess.src.Common.Resources.Oracle.DataAccess.Common.Configuration.Section.xsd")));
			doc.Schemas.Add(null, new XmlTextReader(Assembly.GetExecutingAssembly().GetManifestResourceStream("Oracle.ManagedDataAccess.src.Common.Resources.Oracle.ManagedDataAccess.Client.Configuration.Section.xsd")));
			ValidationEventHandler validationEventHandler = @object.ValidationCallBack;
			doc.Validate(validationEventHandler);
		}

		private void ValidationCallBack(object sender, ValidationEventArgs args)
		{
			if (args.Severity != XmlSeverityType.Warning)
			{
				throw new ConfigurationErrorsException(args.Message);
			}
		}

		internal override void ParseClientXmlNode(XmlNode baseNode, ref Hashtable schemaTable, ref ArrayList versionSpecificNodesList, ArrayList filterNodes = null)
		{
			bool flag = false;
			bool flag2 = false;
			bool flag3 = false;
			foreach (XmlNode childNode in baseNode.ChildNodes)
			{
				if (childNode.Attributes == null || childNode.Attributes["number"].Value == null)
				{
					continue;
				}
				string text = (ConfigBaseClass.m_sectionVersion = childNode.Attributes["number"].Value.Trim());
				if (text == "*")
				{
					if (flag)
					{
						flag3 = true;
					}
					else
					{
						flag = true;
						ParseSubSection(childNode, ref schemaTable, filterNodes);
					}
				}
				else if (text == ConfigBaseClass.m_assemblyVersion.ToString())
				{
					if (flag2)
					{
						flag3 = true;
					}
					else
					{
						flag2 = true;
						versionSpecificNodesList.Add(childNode);
					}
				}
				if (flag3)
				{
					throw new ConfigurationErrorsException($"{childNode.Name} number=\"{text}\" ");
				}
			}
		}
	}
}
